Αφού διάβασα τα κρυμμένα χαρακτηριστικά και τις σκοτεινές γωνίες του C ++ / STL στο comp.lang.c ++. Με εποπτεία, με εξέπληξε εντελώς ότι το παρακάτω απόσπασμα συνέταξε και δούλεψε τόσο στο Visual Studio 2008 όσο και στο G ++ 4.4. Εδώ είναι ο κωδικός: # συμπερίληψηint main () { int x = 10; ενώ (x -> 0) // x πηγαίνει στο 0 { printf ("% d", x); } } Παραγωγή: 9 8 7 6 5 4 3 2 1 0 Θα υποθέσω ότι είναι C, καθώς λειτουργεί και στο GCC. Από πού ορίζεται αυτό στο πρότυπο και από πού προέρχεται;
2020-12-07 21:24:05
-> δεν είναι χειριστής. Στην πραγματικότητα είναι δύο ξεχωριστοί τελεστές, - και>. Ο κώδικας υπό όρους μειώνει το x, ενώ επιστρέφει την αρχική τιμή του x (δεν έχει μειωθεί) και στη συνέχεια συγκρίνει την αρχική τιμή με το 0 χρησιμοποιώντας τον τελεστή>. Για καλύτερη κατανόηση, η δήλωση θα μπορούσε να γραφτεί ως εξής: ενώ ((x--)> 0) | Ή για κάτι εντελώς διαφορετικό ... x διαφάνειες στο 0. ενώ (x - \ \ \ \ > 0) printf ("% d", x); Όχι τόσο μαθηματικά, αλλά ... κάθε εικόνα χρωματίζει χίλιες λέξεις ... | Αυτός είναι ένας πολύ περίπλοκος χειριστής, οπότε ακόμη και το ISO / IEC JTC1 (Κοινή Τεχνική Επιτροπή 1) έβαλε την περιγραφή του σε δύο διαφορετικά μέρη του προτύπου C ++. Αστειεύοντας, είναι δύο διαφορετικοί χειριστές: - και> περιγράφονται αντίστοιχα στα §5.2.6 / 2 και §5.9 του C ++ 03 Standard. | Είναι ισοδύναμο με ενώ (x--> 0) x-- (post decrement) ισοδυναμεί με x = x-1, ο κώδικας μετατρέπεται σε: ενώ (x> 0) { x = x-1; // λογική } Χ--; // Η μείωση μετά έγινε όταν x <= 0 | x μπορεί να πάει στο μηδέν ακόμη πιο γρήγορα στην αντίθετη κατεύθυνση: int x = 10; ενώ (0 <---- x) { printf ("% d", x); } 8 6 4 2 Μπορείτε να ελέγξετε την ταχύτητα με ένα βέλος! int x = 100; ενώ (0 <-------------------- x) { printf ("% d", x); } 90 80 70 60 50 40 30 20 10 ;) | Του # συμπερίληψηint main (άκυρο) { int x = 10; ενώ (x--> 0) {// x πηγαίνει στο 0 printf ("% d", x); } επιστροφή 0; } Μόνο ο χώρος κάνει τα πράγματα να φαίνονται αστεία, - μειώσεις και> συγκρίνει. | Η χρήση του -> έχει ιστορική σημασία. Η μείωση ήταν (και εξακολουθεί να είναι σε ορισμένες περιπτώσεις), γρηγορότερη από την αύξηση της αρχιτεκτονικής x86. Η χρήση -> υποδηλώνει ότι το x πηγαίνει στο 0 και απευθύνεται σε άτομα με μαθηματικό υπόβαθρο. | ενώ (x--> 0) είναι πώς αναλύεται. | Εντελώς geek, αλλά θα το χρησιμοποιήσω: # ορίστε ως; ενώ int main (int argc, char * argv []) { int n = atoi (argv [1]); εκτυπώστε ("το n είναι% d \ n", n) ως (n -> 0); επιστροφή 0; } | Ένα βιβλίο που διάβασα (δεν θυμάμαι σωστά ποιο βιβλίο) δήλωσε: Οι μεταγλωττιστές προσπαθούν να αναλύσουν τις εκφράσεις στο μεγαλύτερο διακριτικό χρησιμοποιώντας τον αριστερό δεξιό κανόνα. Σε αυτήν την περίπτωση, η έκφραση: x -> 0 Αναλύει τα μεγαλύτερα διακριτικά: διακριτικό 1: x διακριτικό 2: - διακριτικό 3:> διακριτικό 4: 0 συμπέρασμα: x--> 0 Ο ίδιος κανόνας ισχύει για αυτήν την έκφραση: α ----- β Μετά την ανάλυση: διακριτικό 1: α διακριτικό 2: - διακριτικό 3: - διακριτικό 4: - διακριτικό 5: β συμπέρασμα: (α -) - - β Ελπίζω ότι αυτό βοηθά στην κατανόηση της περίπλοκης έκφρασης ^^ | Αυτό είναι ακριβώς το ίδιο με ενώ (x--) { printf ("% d", x); } για μη αρνητικούς αριθμούς | Τέλος πάντων, έχουμε έναν χειριστή "πηγαίνει σε" τώρα. "->" είναι εύκολο να θυμηθούμε ως κατεύθυνση, και "ενώ το x πηγαίνει στο μηδέν" σημαίνει ευθεία. Επιπλέον, είναι λίγο πιο αποτελεσματικό από το "for (x = 10; x> 0; x -)" σε ορισμένες πλατφόρμες. | Αυτός ο κωδικός συγκρίνει πρώτα τα x και 0 και στη συνέχεια τις μειώσεις x. (Επίσης, στην πρώτη απάντηση: Είστε μετά τη μείωση του x και, στη συνέχεια, συγκρίνετε τα x και 0 με το χειριστή>.) Δείτε την έξοδο αυτού του κωδικού: 9 8 7 6 5 4 3 2 1 0 Συγκρίνουμε τώρα πρώτα και μετά μειώνοντας βλέποντας 0 στην έξοδο. Εάν θέλουμε πρώτα να μειώσουμε και μετά να συγκρίνουμε, χρησιμοποιήστε αυτόν τον κωδικό: # συμπερίληψη int main (άκυρο) { int x = 10; ενώ (--x> 0) // x πηγαίνει στο 0 { printf ("% d", x); } επιστροφή 0; } Αυτή η έξοδος είναι: 9 8 7 6 5 4 3 2 1 | Ο μεταγλωττιστής μου θα εκτυπώσει 9876543210 όταν εκτελώ αυτόν τον κωδικό. # συμπερίληψη int main () { int x = 10; ενώ (x -> 0) // x πηγαίνει στο 0 { std :: cout << x; } } Οπως αναμενόταν. Το while (x--> 0) σημαίνει στην πραγματικότητα ενώ (x> 0). Οι x - μετά τις μειώσεις x. ενώ (x> 0) { Χ--; std :: cout << x; } είναι ένας διαφορετικός τρόπος να γράφεις το ίδιο πράγμα. Είναι ωραίο ότι το πρωτότυπο μοιάζει με "ενώ το x πηγαίνει στο 0". | Λείπει κενό μεταξύ - και>. Το x είναι post decremented, δηλαδή μειώθηκε μετά τον έλεγχο της συνθήκης x> 0? | - είναι ο τελεστής μείωσης και> είναι ο τελεστής μεγαλύτερος από αυτόν. Οι δύο τελεστές εφαρμόζονται ως ενιαίοι όπως ->. | Είναι ένας συνδυασμός δύο χειριστών. Πρώτον - είναι για τη μείωση της τιμής και> για τον έλεγχο εάν η τιμή είναι μεγαλύτερη από το δεξί τελεστέο. # συμπερίληψη int main () { int x = 10; ενώ (x--> 0) printf ("% d", x); επιστροφή 0; } Η έξοδος θα είναι: 9 8 7 6 5 4 3 2 1 0 | Στην πραγματικότητα, το x είναι μετά τη μείωση και ελέγχεται με αυτήν την κατάσταση Δεν είναι ->, είναι (x--)> 0 Σημείωση: η τιμή του x αλλάζει μετά τον έλεγχο της συνθήκης, επειδή μετά τη μείωση. Ορισμένες παρόμοιες περιπτώσεις μπορούν επίσης να συμβούν, για παράδειγμα: -> x -> 0 ++> x ++> 0 -> = x -> = 0 ++> = x ++> = 0 | Οι C και C ++ συμμορφώνονται με τον κανόνα «μέγιστο munch». Με τον ίδιο τρόπο a --- b μεταφράζεται σε (a--) - b, στην περίπτωσή σας x -> 0 μεταφράζεται σε (x -)> 0. Αυτό που ουσιαστικά λέει ο κανόνας είναι ότι πηγαίνοντας αριστερά προς τα δεξιά, οι εκφράσεις σχηματίζονται λαμβάνοντας το μέγιστο των χαρακτήρων που θα σχηματίσουν μια έγκυρη έκφραση. | Γιατί όλη η επιπλοκή; Η απλή απάντηση στην αρχική ερώτηση είναι απλώς: # συμπερίληψη int main () { int x = 10; ενώ (x>0) { printf ("% d", x); x = x-1; } } Κάνει το ίδιο πράγμα. Δεν λέω ότι πρέπει να το κάνετε έτσι, αλλά κάνει το ίδιο πράγμα και θα απαντούσατε στην ερώτηση σε μία ανάρτηση. Το x-- είναι μόνο συντομογραφία για τα παραπάνω και> είναι απλώς ένας κανονικός μεγαλύτερος από τον τελεστή. Χωρίς μεγάλο μυστήριο! Υπάρχουν πάρα πολλοί άνθρωποι που κάνουν τα απλά πράγματα περίπλοκα σήμερα;) | Με τον συμβατικό τρόπο θα ορίζαμε μια συνθήκη στην παρένθεση while loop () και μια συνθήκη τερματισμού μέσα στα άγκιστρα {}, αλλά -> ορίζει και τα δύο ταυτόχρονα. Για παράδειγμα: int abc (άκυρο) { int a = 5 ενώ ((a--)> 0) // Μείωση και σύγκριση και τα δύο ταυτόχρονα { // Κωδικός } } Αυτό μειώνεται και τρέχει το βρόχο ενώ το α είναι μεγαλύτερο από 0. Συμβατικά, θα ήταν σαν: int abc (άκυρο) { int a = 5; ενώ (a> 0) { ένα--; // Κωδικός } ένα--; } Και με τους δύο τρόπους, κάνουμε το ίδιο πράγμα και επιτυγχάνουμε τους ίδιους στόχους. | (x -> 0) σημαίνει (x--> 0). Μπορείτε να χρησιμοποιήσετε (x ->) Έξοδος: 9 8 7 6 5 4 3 2 1 0 Μπορείτε να χρησιμοποιήσετε (- x> 0) Είναι μέση (--x> 0) Έξοδος: 9 8 7 6 5 4 3 2 1 Μπορείς να χρησιμοποιήσεις (- \ \ x> 0) Έξοδος: 9 8 7 6 5 4 3 2 1 Μπορείς να χρησιμοποιήσεις (\ \ x -> 0) Έξοδος: 9 8 7 6 5 4 3 2 1 0 Μπορείς να χρησιμοποιήσεις (\ \ x -> 0 \ \ ) Έξοδος: 9 8 7 6 5 4 3 2 1 0 Μπορείτε επίσης να χρησιμοποιήσετε ( Χ -> ) Έξοδος: 9 8 7 6 5 4 3 2 1 0 Ομοίως, μπορείτε να δοκιμάσετε πολλές μεθόδους για να εκτελέσετε αυτήν την εντολή με επιτυχία. | Εδώ - είναι ο μη λειτουργικός τελεστής μετά τη μείωση. ενώ (x--> 0) // x πηγαίνει στο 0 { printf ("% d", x); } Στην αρχή, η κατάσταση θα αξιολογηθεί ως (x> 0) // 10> 0 Τώρα επειδή η συνθήκη είναι αληθινή, θα πάει στο βρόχο με μια μειωμένη τιμή x-- // x = 9 Γι 'αυτό η πρώτη εκτυπωμένη τιμή είναι 9 Και ούτω καθεξής. Στο τελευταίο βρόχο x = 1, έτσι η συνθήκη είναι αληθής. Σύμφωνα με τον unary τελεστή, η τιμή άλλαξε σε x = 0 τη στιγμή της εκτύπωσης. Τώρα, x = 0, που αξιολογεί την κατάσταση (x> 0) ως ψευδής και ο βρόχος while εξέρχεται. | Αυτό -> δεν είναι καθόλου χειριστής. Έχουμε έναν χειριστή όπως ->, αλλά όχι όπως ->. Είναι απλώς μια λανθασμένη ερμηνεία του while (x--> 0) που σημαίνει απλά ότι x έχει τον τελεστή μετά τη μείωση και αυτός ο βρόχος θα τρέξει μέχρι να είναι μεγαλύτερος από το μηδέν. Ένας άλλος απλός τρόπος σύνταξης αυτού του κώδικα θα ήταν το (x--). Ο βρόχος while θα σταματήσει κάθε φορά που παίρνει μια λανθασμένη κατάσταση και εδώ υπάρχει μόνο μία περίπτωση, δηλαδή 0. Έτσι θα σταματήσει όταν η τιμή x μειώνεται στο μηδέν. | Πολύ ενεργή ερώτηση. Κερδίστε 10 φήμη για να απαντήσετε σε αυτήν την ερώτηση. Η απαίτηση φήμης συμβάλλει στην προστασία αυτής της ερώτησης από ανεπιθύμητες ενέργειες και μη απαντήσεις. Δεν είναι η απάντηση που ψάχνετε; Περιηγηθείτε σε άλλες ερωτήσεις με ετικέτες χειριστών c ++ c πρότυπα-μορφοποίηση προτύπων-συμμόρφωση ή κάντε τη δική σας ερώτηση.